package com.cchr.acms.controller;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.cchr.acms.ConfigInfo;
import com.cchr.acms.constant.CaseStatus;
import com.cchr.acms.model.AbuseType;
import com.cchr.acms.model.AbusedPerson;
import com.cchr.acms.model.Action;
import com.cchr.acms.model.AjaxResult;
import com.cchr.acms.model.Attorney;
import com.cchr.acms.model.CaseAudit;
import com.cchr.acms.model.CaseFollowUp;
import com.cchr.acms.model.CaseInfo;
import com.cchr.acms.model.CaseInfoQueryEntity;
import com.cchr.acms.model.CaseInfoResult;
import com.cchr.acms.model.Chapter;
import com.cchr.acms.model.DoctorInfo;
import com.cchr.acms.model.Drug;
import com.cchr.acms.model.FacilityInfo;
import com.cchr.acms.model.ReportingPerson;
import com.cchr.acms.model.User;
import com.cchr.acms.service.AbuseTypeService;
import com.cchr.acms.service.AbusedPersonService;
import com.cchr.acms.service.ActionService;
import com.cchr.acms.service.AttorneyService;
import com.cchr.acms.service.CaseAuditService;
import com.cchr.acms.service.CaseFollowUpService;
import com.cchr.acms.service.CaseInfoService;
import com.cchr.acms.service.CaseService;
import com.cchr.acms.service.ChapterService;
import com.cchr.acms.service.DoctorInfoService;
import com.cchr.acms.service.DrugService;
import com.cchr.acms.service.FacilityInfoService;
import com.cchr.acms.service.NotificationService;
import com.cchr.acms.service.ReportingPersonService;
import com.cchr.acms.service.UserService;
import com.cchr.acms.util.ChangeHistoryDisplayData;
import com.cchr.acms.util.ChangeResult;
import com.cchr.acms.util.DataTableVO;
import com.cchr.acms.util.DataUtil;
import com.cchr.acms.util.HtmlComponentUtil.SelectOption;
import com.cchr.acms.util.PageableDataVO;
import com.cchr.acms.util.UserAgentUtils;

import net.sf.json.JSONObject;

@Controller
@RequestMapping("/case")
public class CaseInfoController {
	@Autowired
	private CaseService caseService;
	@Autowired
	private CaseInfoService caseInfoService;
	@Autowired
	private AbusedPersonService abusedPersonService;
	@Autowired
	private ReportingPersonService reportingPersonService;
	@Autowired
	private DrugService drugService;
	@Autowired
	private AbuseTypeService abuseTypeService;
	@Autowired
	private FacilityInfoService FacilityInfoService;
	@Autowired
	private DoctorInfoService doctorInfoService;
	@Autowired
	private AttorneyService attorneyService;
	@Autowired
	private ActionService actionService;
	@Autowired
	private CaseFollowUpService caseFollowUpService;
	@Autowired
	private CaseAuditService caseAuditService;
	@Autowired
	private NotificationService notificationService;
	@Autowired
	private ConfigInfo configInfo;
	@Autowired
    private UserService userService;
	@Autowired
	private ChapterService chapterService;
	
	private static final Logger operateLogger = LoggerFactory.getLogger("operateLog");
	private static final Logger exceptionLog = LoggerFactory.getLogger("exceptionLog");
	 
	@RequestMapping(value={"/createByMobile"}, method = RequestMethod.GET)
	public String createPageByMobile(HttpServletRequest request){
		return genCreatePage(request);
	}
	
	@RequestMapping(value={"/create"}, method = RequestMethod.GET)
	public String createPage(HttpServletRequest request){
		return genCreatePage(request);
	}
	
	public String genCreatePage(HttpServletRequest request){
    	List<Drug> drugs = drugService.getAllDrug();
    	
    	List<SelectOption> datas = new ArrayList<SelectOption>();
    	for(Drug drug : drugs)
    	{
    		SelectOption op = new SelectOption();
    		op.setGroup(drug.getType());
    		op.setLabel(drug.getName());
    		op.setValue(String.valueOf(drug.getId()));
    		datas.add(op);
    	}
    	request.setAttribute("datas", datas);
    	
    	List<SelectOption> countryDatas = new ArrayList<SelectOption>();
    	for (int i = 0; i < CaseService.COUNTRY.length; i++) {
    		SelectOption op = new SelectOption();
    		op.setLabel(CaseService.COUNTRY[i]);
    		op.setValue(CaseService.COUNTRY[i]);
    		countryDatas.add(op);
		}
    	request.setAttribute("countryDatas", countryDatas);
    	
    	List<AbuseType> abuseTypes = abuseTypeService.getAllAbuseType();
    	request.setAttribute("abuseTypes", abuseTypes);
    	
    	List<Action> actions = actionService.getAllAction();
    	request.setAttribute("actions", actions);
    	
    	List<SelectOption> docTypes = new ArrayList<SelectOption>();
    	for (int i = 0; i < CaseService.DOCTYPE.length; i++) {
    		SelectOption op = new SelectOption();
    		op.setLabel(CaseService.DOCTYPE[i]);
    		op.setValue(CaseService.DOCTYPE[i]);
    		docTypes.add(op);
		}
    	request.setAttribute("docTypes", docTypes);
    	
    	List<SelectOption> relations = new ArrayList<SelectOption>();
    	for (int i = 0; i < CaseService.RELATION.length; i++) {
    		SelectOption op = new SelectOption();
    		op.setLabel(CaseService.RELATION[i]);
    		op.setValue(CaseService.RELATION[i]);
    		relations.add(op);
		}
    	request.setAttribute("relations", relations);
    	
    	List<SelectOption> facilityTypes = new ArrayList<SelectOption>();
    	for (int i = 0; i < CaseService.FACILITY_TYPE.length; i++) {
    		SelectOption op = new SelectOption();
    		op.setLabel(CaseService.FACILITY_TYPE[i]);
    		op.setValue(CaseService.FACILITY_TYPE[i]);
    		facilityTypes.add(op);
		}
    	request.setAttribute("facilityTypes", facilityTypes);
    	request.setAttribute("insuranceType", CaseService.INSURANCE_TYPE);
    	String page = "case/create";
    	if(UserAgentUtils.isMobileOrTablet(request))
    	{
    		page = "case/create_phone";
    	}
    	return page;
	}
	
	@RequestMapping(value={"/create"}, method = RequestMethod.POST)
	public String addCase(HttpServletRequest request,CaseInfo caseInfo,String[] drugIds,String[] actionsCheckbox,String[] abusetypeCheckbox,String[] insuranceTypeCheckbox,HttpSession session) throws Exception{
		String currUser = (String)request.getSession().getAttribute("userName");
		caseService.addCase(caseInfo, drugIds, actionsCheckbox, abusetypeCheckbox, insuranceTypeCheckbox,currUser);	    
	try{
		sendNotification(caseInfo, "1",null,null);
	}catch(Exception ex){
		exceptionLog.error("send notification error when abuse case created!");
		exceptionLog.error(ex.toString());
	}
		
		return "redirect:create/success/" + caseInfo.getId();
	}
	/* when a=1, send mail to cchr int user which in cfg file when new abuse case created, toEmail = null
	 * when a=2 , send mail to assigned user's mail address , toEmail have to passed
	*/
	public void sendNotification(CaseInfo caseInfo, String a, String toEmail, String notes) throws Exception{ 
		String subject="";
		String notifyEmail="";
		StringBuffer emailContent = new StringBuffer();
		
		if (a=="1"){
			 notifyEmail=configInfo.getNotifyTo();
			emailContent.append("<div>"+
					"Hi," +
					"<br><br>"+
					"CCHR abuse case management system just received a new case " + caseInfo.getCaseNo() + " from your CCHR website!");
			 subject = "A new abuse case "+caseInfo.getCaseNo()+ " received!";
		}
		if (a=="2"){
			notifyEmail=toEmail.trim();
			emailContent.append("<div>"+
					"Hi," +
					"<br><br>"+
					"A new case " + caseInfo.getCaseNo() + " has been assigned to you from CCHR INT.");
			 subject = "A new abuse case "+caseInfo.getCaseNo()+ " has been assigned to you!";
		}
		emailContent.append("<br><br>");
		emailContent.append("Please click "+ "<a href="+configInfo.getAcmsUrl()+">"+ configInfo.getAcmsUrl()+"</a>"+" to see more details.");
		if("2"==a){
			emailContent.append("<br><br>");
			emailContent.append("Notes:");
			emailContent.append("<br><br>");
			emailContent.append(notes);
		}
		emailContent.append("<br><br>");
		emailContent.append("<br><br>");
		emailContent.append("<br><br>");
		emailContent.append("Regards,");
		emailContent.append("<br><br>");
		emailContent.append("[Abuse Case Management System]");
		emailContent.append("<br><br>");
		emailContent.append("------------------------------------------------------------------------------------------------");
		emailContent.append("<br><br>");
		emailContent.append("Please DO NOT reply this email, it's generated by ACMS system automatically.");
		emailContent.append("<br><br>");
		emailContent.append("-------------------------------------------------------------------------------------------------");
		emailContent.append("</div>");
		
		String fromEmaill = configInfo.getFromEmail();
		notificationService.sendHtmlMailWithoutAttached(fromEmaill, notifyEmail, subject, emailContent.toString());
		operateLogger.info("send notification"+a+" mail successfully!");
	}

	
	@RequestMapping(value={"/create/success/{id}"}, method = RequestMethod.GET)
	public String createSuccessPage(@PathVariable Integer id) throws ParseException{
		return "/case/create_success";
	}
	
	@RequestMapping(value={"/create/success/{id}"}, method = RequestMethod.POST)
	public String createSuccess(String emailAddress, @PathVariable Integer id) throws ParseException{
		
		CaseInfo caseInfo = caseInfoService.getCaseInfoById(id);
		
		caseInfo.setSubEmail(emailAddress);
		
		JSONObject caseInfoObject=JSONObject.fromObject(caseInfo);
        operateLogger.info("[case/success-updateCaseInfo]--Start--["+caseInfoObject.toString()+"]");
        
		caseInfoService.updateCaseInfo(caseInfo);
		return "redirect:https://www.cchrint.org/newsletter-subscription/?email=";
	}
	
	@RequestMapping(value={"/showAbuseList"})
	public String showAbuseList(HttpServletRequest request){
		//List<String> countries = chapterService.queryAllCountries();
    	List<SelectOption> countryDatas = new ArrayList<SelectOption>();
    	if(CaseService.COUNTRY != null && CaseService.COUNTRY.length > 0)
    	{
    		for (int i = 0; i < CaseService.COUNTRY.length; i++) {
        		SelectOption op = new SelectOption();
        		op.setLabel(CaseService.COUNTRY[i]);
        		op.setValue(CaseService.COUNTRY[i]);
        		countryDatas.add(op);
    		}
    	}
    	request.setAttribute("countryDatas", countryDatas);
    	
    	List<SelectOption> facilityTypes = new ArrayList<SelectOption>();
    	for (int i = 0; i < CaseService.FACILITY_TYPE.length; i++) {
    		SelectOption op = new SelectOption();
    		op.setLabel(CaseService.FACILITY_TYPE[i]);
    		op.setValue(CaseService.FACILITY_TYPE[i]);
    		facilityTypes.add(op);
		}
    	request.setAttribute("facilityTypes", facilityTypes);
    	
    	List<SelectOption> docTypes = new ArrayList<SelectOption>();
    	for (int i = 0; i < CaseService.DOCTYPE.length; i++) {
    		SelectOption op = new SelectOption();
    		op.setLabel(CaseService.DOCTYPE[i]);
    		op.setValue(CaseService.DOCTYPE[i]);
    		docTypes.add(op);
		}
    	request.setAttribute("docTypes", docTypes);
    	
    	List<Drug> drugs = drugService.getAllDrug();
    	List<SelectOption> datas = new ArrayList<SelectOption>();
    	List<String> drugTypes = new ArrayList<String>();
    	List<SelectOption> drugTypeOptions = new ArrayList<SelectOption>();
    	for(Drug drug : drugs)
    	{
    		SelectOption op = new SelectOption();
    		op.setGroup(drug.getType());
    		op.setLabel(drug.getName());
    		op.setValue(String.valueOf(drug.getId()));
    		datas.add(op);
    		if(!drugTypes.contains(drug.getType())){
    			drugTypes.add(drug.getType());
    		}
    	}
    	request.setAttribute("drugs", datas);
    	
    	for(String dn : drugTypes)
    	{
    		SelectOption op = new SelectOption();
    		op.setLabel(dn);
    		op.setValue(dn);
    		drugTypeOptions.add(op);
    	}
    	request.setAttribute("drugTypeOptions", drugTypeOptions);
    	
    	List<SelectOption> abuseTypes = new ArrayList<SelectOption>();
    	List<AbuseType> abuseList = abuseTypeService.getAllAbuseType();
    	for (AbuseType abuseType : abuseList) {
    		SelectOption op = new SelectOption();
    		op.setLabel(abuseType.getName());
    		op.setValue(abuseType.getId()+"");
    		abuseTypes.add(op);
		}
    	request.setAttribute("abuseTypes", abuseTypes);
    	
    	List<SelectOption> insTypes = new ArrayList<SelectOption>();
    	for (int i = 0; i < CaseService.INSURANCE_TYPE.length; i++) {
    		SelectOption op = new SelectOption();
    		op.setLabel(CaseService.INSURANCE_TYPE[i]);
    		op.setValue(CaseService.INSURANCE_TYPE[i]);
    		insTypes.add(op);
		}
    	request.setAttribute("insTypes", insTypes);
    	
    	return "case/showCase";
	}
	
	@RequestMapping(value={"/showAbuseListJson"}, method = RequestMethod.POST)
    @ResponseBody
    public PageableDataVO<CaseInfoResult> getAbuseList(DataTableVO dataTableVO, CaseInfoQueryEntity queryEntity,HttpServletRequest request) {

		SimpleDateFormat dateFormat=new SimpleDateFormat("MM/dd/yyyy");  
		//解析
		int index = dataTableVO.getStart();
		int offset = dataTableVO.getLength();
		PageableDataVO<CaseInfoResult> data = new PageableDataVO<CaseInfoResult>();
		List<CaseInfoResult> result = new ArrayList<CaseInfoResult>();
        try {
    		String username = (String) request.getSession().getAttribute("userType");
    		if(username.equals("3")){
    			User user = (User) request.getSession().getAttribute("user");
    			queryEntity.setUserId(user.getId());
    		}
        	List<CaseInfo> list = caseInfoService.queryAbuseInfo(queryEntity,index,offset);
        	int total = caseInfoService.queryTotal(queryEntity);
        	data.setiTotalDisplayRecords(total);
    		data.setiTotalRecords(total);
        	for (int i = 0; i < list.size(); i++) {
        		list.get(i).setStatus(CaseStatus.getKeyByValue(list.get(i).getStatus()));
        		AbusedPerson abusedPerson = abusedPersonService.getAbusedPersonByCaseId(list.get(i).getId());
        		list.get(i).setAbusedPerson(abusedPerson);
        		List<DoctorInfo> doctorInfos = doctorInfoService.queryDoctorInfoByCaseId(list.get(i).getId());
        		list.get(i).setDoctorInfos(doctorInfos);
        		List<FacilityInfo> facilityInfos = FacilityInfoService.getFacilityInfoByCaseId(list.get(i).getId());
        		list.get(i).setFacilityInfos(facilityInfos);
        		CaseInfoResult rs = new CaseInfoResult();
        		// mock data
        		rs.setSequence(list.get(i).getCaseNo());
        		if(StringUtils.isEmpty(list.get(i).getUserId()))
        		{
        			rs.setProcessedBy("CCHR INT");
        		}
        		else
        		{
        			User user = userService.getUserById(Integer.valueOf(list.get(i).getUserId()));
        			Chapter chapter = chapterService.queryChapterById(user.getChapterId());
        			if(chapter == null)
        			{
        				rs.setProcessedBy("CCHR INT");
        			}
        			else
        			{
        				rs.setProcessedBy(chapter.getChapter());
        			}
        		}
        		// mock end
        		rs.setId(list.get(i).getId());
        		//patient name
        		rs.setPatientName(list.get(i).getAbusedPerson().getFirstName() + " " + list.get(i).getAbusedPerson().getLastName());
        		//create time
        		rs.setCreateTime(list.get(i).getCreateDate());
        		//status
        		rs.setStatus(list.get(i).getStatus().toUpperCase());
        		rs.setCity(list.get(i).getAbusedPerson().getCity());
        		rs.setLastUpdateDate(list.get(i).getLastUpdateDate());
        		if(rs.getLastUpdateDate() != null)
        		{
        			rs.setLastUpdateDateStr(dateFormat.format(rs.getLastUpdateDate()));
        		}
        		rs.setAssignedUserId(list.get(i).getUserId());
        		rs.setLastUpdatedBy(list.get(i).getLastUpdatedBy());
        		//doctor name
        		List<DoctorInfo> dlist = list.get(i).getDoctorInfos();
        		StringBuilder sb = new StringBuilder();
        		if(dlist!=null&&(dlist.size()>0)){
        			for (int j = 0; j < dlist.size(); j++) {
        				String  docNameString = StringUtils.trimToEmpty(dlist.get(j).getName());
        				if(StringUtils.isNotBlank(docNameString))
        				{
        					docNameString += " ";
        				}
        				docNameString += StringUtils.trimToEmpty(dlist.get(j).getLastName());
						if(StringUtils.isNotBlank(docNameString))
						{
							if(sb.length() > 0)
							{
								sb.append(",");
							}
							sb.append(docNameString);
						}
					}
        		}
        		rs.setDoctorName(sb.toString());
        		
        		//facility name
        		List<FacilityInfo> flist = list.get(i).getFacilityInfos();
        		sb = new StringBuilder();
        		if(flist!=null && flist.size()>0){
        			for (int j = 0; j < flist.size(); j++) {
        				if(StringUtils.isNotBlank(flist.get(j).getName()))
						{
        					if(sb.length() > 0)
							{
								sb.append(",");
							}
							sb.append(flist.get(j).getName());;
						}
					}
        		}
        		rs.setFacilityName(sb.toString());
        	
        		result.add(rs);
			}
        	data.addData(result);
            return data;

        } catch (Exception e) {
        	e.printStackTrace();
            return data;
        }
    }

	
	@RequestMapping(value={"/detail/{id}"}, method = RequestMethod.GET)
	public String detailPage(HttpServletRequest request, @PathVariable Integer id, String edit, String tab)
	{
		request.setAttribute("edit", edit);
		request.setAttribute("tab", tab);
		if(id != null)
		{
			CaseInfo caseInfo = caseInfoService.getCaseInfoById(id);
			request.setAttribute("caseStatus", CaseStatus.getList());
			if(caseInfo != null)
			{
				AbusedPerson abusedPerson = abusedPersonService.getAbusedPersonByCaseId(id);
				caseInfo.setAbusedPerson(abusedPerson);
				ReportingPerson reportingPerson = reportingPersonService.getReportingPersonByCaseId(id);
				caseInfo.setReportedBy(reportingPerson);
				Attorney attorney = attorneyService.getAttorneyByCaseId(id);
				caseInfo.setAttorney(attorney);
				List<DoctorInfo> doctorInfos = doctorInfoService.queryDoctorInfoByCaseId(id);
				caseInfo.setDoctorInfos(doctorInfos);
				List<FacilityInfo> facilityInfos = FacilityInfoService.getFacilityInfoByCaseId(id);
				
				caseInfo.setFacilityInfos(facilityInfos);
				
				String typeIds = caseInfo.getTypeIds();
				if(typeIds != null)
				{
					StringBuilder sb = new StringBuilder();
					String[] typeIdArr = typeIds.split(",");
					if(typeIdArr.length > 0)
					{
						List<String> typeIdList = Arrays.asList(typeIdArr);
						List<AbuseType> abuseTypes = abuseTypeService.getAllAbuseType();
				    	for(AbuseType type : abuseTypes)
				    	{
				    		if(typeIdList.contains(String.valueOf(type.getId())))
				    		{
				    			sb.append(type.getName()).append(", ");
				    		}
				    	}
					}
					if(sb.lastIndexOf(",") == sb.length() - 2)
					{
						sb.delete(sb.length() - 2, sb.length());
					}
					request.setAttribute("typeIds", sb.toString());
				}
				
				String drugIds = caseInfo.getDrugIds();
				if(drugIds != null)
				{
					String[] drugIdArr = drugIds.split(",");
					if(drugIdArr.length > 0)
					{
						List<String> drugIdList = Arrays.asList(drugIdArr);
						List<Drug> drugs = drugService.getAllDrug();
						List<String> drugNames = new ArrayList<String>();
				    	for(Drug drug : drugs)
				    	{
				    		if(drugIdList.contains(String.valueOf(drug.getId())))
				    		{
				    			drugNames.add(drug.getName());
				    		}
				    	}
				    	request.setAttribute("drugNames", drugNames);
					}
				}
				
				String actionIds = caseInfo.getActionIds();
				if(actionIds != null)
				{
					String[] actionIdArr = actionIds.split(",");
					if(actionIdArr.length > 0)
					{
						List<String> actionIdList = Arrays.asList(actionIdArr);
						List<Action> actions = actionService.getAllAction();
						List<String> acs = new ArrayList<String>();
				    	for(Action action : actions)
				    	{
				    		if(actionIdList.contains(String.valueOf(action.getId())))
				    		{
				    			acs.add(action.getName());
				    		}
				    	}
				    	request.setAttribute("actions", acs);
					}
				}
				String insuranceTypes = caseInfo.getInsuranceType();
				if(insuranceTypes!=null){
					String[] types = insuranceTypes.split(",");
					if(types.length>0){
						List<String> insuranceTypeList = Arrays.asList(types);
						request.setAttribute("insuranceType", insuranceTypeList);
					}
					
				}
				
				request.setAttribute("caseInfo", caseInfo);
			}
			// audit list
			List<CaseAudit> caseAudits = caseAuditService.getAllCaseAuditByCaseId(caseInfo.getId());
			request.setAttribute("caseAudits", caseAudits);
			CaseFollowUp followup = caseFollowUpService.getCaseFollowUpByCaseId(id);

			if(followup == null)
			{
				followup = new CaseFollowUp();
			}
			request.setAttribute("contactWays", CaseService.CONTATC_WAY);
			request.setAttribute("insuranceType", CaseService.INSURANCE_TYPE);
			request.setAttribute("attorneyStatus", CaseService.ATTORNEY_STATUS);
			request.setAttribute("followup", followup);
			
			// 根据类型设置不同的Staff Memeber Name
			if(followup != null)
			{
				if("0".equals(followup.getFollowedType()))
				{
					followup.setStaffMemeberFirstName1(followup.getStaffMemeberFirstName());
					followup.setStaffMemeberLastName1(followup.getStaffMemeberLastName());
				}
				else
				{
					followup.setStaffMemeberFirstName2(followup.getStaffMemeberFirstName());
					followup.setStaffMemeberLastName2(followup.getStaffMemeberLastName());
				}
			}
			
	    	List<SelectOption> countryDatas = new ArrayList<SelectOption>();
	    	for (int i = 0; i < CaseService.COUNTRY.length; i++) {
	    		SelectOption op = new SelectOption();
	    		op.setLabel(CaseService.COUNTRY[i]);
	    		op.setValue(CaseService.COUNTRY[i]);
	    		countryDatas.add(op);
			}
	    	List<SelectOption> caseCategory = new ArrayList<SelectOption>();
	    	for(int i=1; i<6; i++)
	    	{
	    		SelectOption op = new SelectOption();
	    		op.setLabel(i + "");
	    		op.setValue(i + "");
	    		caseCategory.add(op);
	    	}
	    	request.setAttribute("caseCategory", caseCategory);
	    	request.setAttribute("countryDatas", countryDatas);
	    	if(edit == null || StringUtils.isEmpty(edit))
	    	{
	    		return "case/detail/followup";
	    	}
	    	else
	    	{
	    		return "case/detail/editfollowup";
	    	}
		}
    	
		return "case/detail/followup";
	}
	
	@RequestMapping(value={"/detail/{id}"}, method = RequestMethod.POST)
	public String addDetail(HttpServletRequest request, CaseFollowUp caseFollowUp, @PathVariable Integer id, String caseStatus,
			String[] contactWaysCheckbox, String[] insuranceTypeCheckbox, String[] attorneyStatusCheckbox) throws Exception{
		String currUser = (String)request.getSession().getAttribute("userName");
		caseService.addDetail(caseFollowUp, id, caseStatus, contactWaysCheckbox, insuranceTypeCheckbox, attorneyStatusCheckbox, currUser);
		return "redirect:/case/detail/" + id + "?tab=2";
	}
	
	@RequestMapping(value={"/edit/{id}"}, method = RequestMethod.GET)
	public String editPage(HttpServletRequest request, @PathVariable Integer id)
	{
		if(id != null)
		{
			CaseInfo caseInfo = caseInfoService.getCaseInfoById(id);
			request.setAttribute("caseStatus", CaseStatus.getList());
			// audit list
			List<CaseAudit> caseAudits = caseAuditService.getAllCaseAuditByCaseId(caseInfo.getId());
			request.setAttribute("caseAudits", caseAudits);
			if(caseInfo != null)
			{
				AbusedPerson abusedPerson = abusedPersonService.getAbusedPersonByCaseId(id);
				caseInfo.setAbusedPerson(abusedPerson);
				ReportingPerson reportingPerson = reportingPersonService.getReportingPersonByCaseId(id);
				caseInfo.setReportedBy(reportingPerson);
				Attorney attorney = attorneyService.getAttorneyByCaseId(id);
				caseInfo.setAttorney(attorney);
				List<DoctorInfo> doctorInfos = doctorInfoService.queryDoctorInfoByCaseId(id);
				if(doctorInfos.size() == 1)
				{
					doctorInfos.add(new DoctorInfo());
				}
				caseInfo.setDoctorInfos(doctorInfos);
				List<FacilityInfo> facilityInfos = FacilityInfoService.getFacilityInfoByCaseId(id);
				if(facilityInfos.size() == 1)
				{
					facilityInfos.add(new FacilityInfo());
				}
				caseInfo.setFacilityInfos(facilityInfos);
				
				String typeIds = caseInfo.getTypeIds();
				if(typeIds != null)
				{
					StringBuilder sb = new StringBuilder();
					String[] typeIdArr = typeIds.split(",");
					if(typeIdArr.length > 0)
					{
						List<String> typeIdList = Arrays.asList(typeIdArr);
						List<AbuseType> abuseTypes = abuseTypeService.getAllAbuseType();
				    	for(AbuseType type : abuseTypes)
				    	{
				    		if(typeIdList.contains(String.valueOf(type.getId())))
				    		{
				    			sb.append(type.getName()).append(", ");
				    		}
				    	}
					}
					if(sb.lastIndexOf(",") == sb.length() - 2)
					{
						sb.delete(sb.length() - 2, sb.length());
					}
					request.setAttribute("typeIds", sb.toString());
				}
				
				String drugIds = caseInfo.getDrugIds();
				if(drugIds != null)
				{
					String[] drugIdArr = drugIds.split(",");
					if(drugIdArr.length > 0)
					{
						List<String> drugIdList = Arrays.asList(drugIdArr);
						List<Drug> drugs = drugService.getAllDrug();
						List<String> drugNames = new ArrayList<String>();
				    	for(Drug drug : drugs)
				    	{
				    		if(drugIdList.contains(String.valueOf(drug.getId())))
				    		{
				    			drugNames.add(drug.getName());
				    		}
				    	}
				    	request.setAttribute("drugNames", drugNames);
					}
				}
				
				String actionIds = caseInfo.getActionIds();
				if(actionIds != null)
				{
					String[] actionIdArr = actionIds.split(",");
					if(actionIdArr.length > 0)
					{
						List<String> actionIdList = Arrays.asList(actionIdArr);
						List<Action> actions = actionService.getAllAction();
						List<String> acs = new ArrayList<String>();
				    	for(Action action : actions)
				    	{
				    		if(actionIdList.contains(String.valueOf(action.getId())))
				    		{
				    			acs.add(action.getName());
				    		}
				    	}
				    	request.setAttribute("myactions", acs);
					}
				}
				
				List<String> insuranceList = Arrays.asList(CaseService.INSURANCE_TYPE);
				request.setAttribute("insuranceType", insuranceList);
				request.setAttribute("caseInfo", caseInfo);
			}
			CaseFollowUp followup = caseFollowUpService.getCaseFollowUpByCaseId(id);
			if(followup == null)
			{
				followup = new CaseFollowUp();
			}
			request.setAttribute("contactWays", CaseService.CONTATC_WAY);
			
			request.setAttribute("attorneyStatus", CaseService.ATTORNEY_STATUS);
			request.setAttribute("followup", followup);
			
			// 根据类型设置不同的Staff Memeber Name
			if(followup != null)
			{
				if("0".equals(followup.getFollowedType()))
				{
					followup.setStaffMemeberFirstName1(followup.getStaffMemeberFirstName());
					followup.setStaffMemeberLastName1(followup.getStaffMemeberLastName());
				}
				else
				{
					followup.setStaffMemeberFirstName2(followup.getStaffMemeberFirstName());
					followup.setStaffMemeberLastName2(followup.getStaffMemeberLastName());
				}
			}
			
	    	List<SelectOption> countryDatas = new ArrayList<SelectOption>();
	    	for (int i = 0; i < CaseService.COUNTRY.length; i++) {
	    		SelectOption op = new SelectOption();
	    		op.setLabel(CaseService.COUNTRY[i]);
	    		op.setValue(CaseService.COUNTRY[i]);
	    		countryDatas.add(op);
			}
	    	List<SelectOption> caseCategory = new ArrayList<SelectOption>();
	    	for(int i=1; i<6; i++)
	    	{
	    		SelectOption op = new SelectOption();
	    		op.setLabel(i + "");
	    		op.setValue(i + "");
	    		caseCategory.add(op);
	    	}
	    	request.setAttribute("caseCategory", caseCategory);
	    	request.setAttribute("countryDatas", countryDatas);
	    	
	    	List<SelectOption> relations = new ArrayList<SelectOption>();
	    	for (int i = 0; i < CaseService.RELATION.length; i++) {
	    		SelectOption op = new SelectOption();
	    		op.setLabel(CaseService.RELATION[i]);
	    		op.setValue(CaseService.RELATION[i]);
	    		relations.add(op);
			}
	    	request.setAttribute("relations", relations);
	    	
	    	List<AbuseType> abuseTypes = abuseTypeService.getAllAbuseType();
	    	request.setAttribute("abuseTypes", abuseTypes);
	    	
	    	String typeIdStr = caseInfo.getTypeIds();
			List<String> typeIds = new ArrayList<String>();
			if(typeIdStr != null)
			{
				typeIds = Arrays.asList(typeIdStr.split(","));
			}
			request.setAttribute("typeIds", typeIds);
			
			List<SelectOption> facilityTypes = new ArrayList<SelectOption>();
	    	for (int i = 0; i < CaseService.FACILITY_TYPE.length; i++) {
	    		SelectOption op = new SelectOption();
	    		op.setLabel(CaseService.FACILITY_TYPE[i]);
	    		op.setValue(CaseService.FACILITY_TYPE[i]);
	    		facilityTypes.add(op);
			}
	    	request.setAttribute("facilityTypes", facilityTypes);
	    	
	    	List<Action> actions = actionService.getAllAction();
	    	request.setAttribute("actions", actions);
	    	
	    	List<SelectOption> docTypes = new ArrayList<SelectOption>();
	    	for (int i = 0; i < CaseService.DOCTYPE.length; i++) {
	    		SelectOption op = new SelectOption();
	    		op.setLabel(CaseService.DOCTYPE[i]);
	    		op.setValue(CaseService.DOCTYPE[i]);
	    		docTypes.add(op);
			}
	    	request.setAttribute("docTypes", docTypes);
	    	
	    	List<Drug> drugs = drugService.getAllDrug();
	    	List<SelectOption> datas = new ArrayList<SelectOption>();
	    	for(Drug drug : drugs)
	    	{
	    		SelectOption op = new SelectOption();
	    		op.setGroup(drug.getType());
	    		op.setLabel(drug.getName());
	    		op.setValue(String.valueOf(drug.getId()));
	    		datas.add(op);
	    	}
	    	request.setAttribute("datas", datas);
	    	
	    	List<String> drugIdList = new ArrayList<String>();
	    	String drugIds = caseInfo.getDrugIds();
			if(drugIds != null)
			{
				String[] drugIdArr = drugIds.split(",");
				if(drugIdArr.length > 0)
				{
					drugIdList = Arrays.asList(drugIdArr);
				}
			}
			request.setAttribute("drugIdList", drugIdList);
			
			List<String> actionIdList = new ArrayList<String>();
			String actionIds = caseInfo.getActionIds();
			if(actionIds != null)
			{
				actionIdList = Arrays.asList(actionIds.split(","));
			}
			request.setAttribute("actionIdList", actionIdList);
		}
		return "case/edit";
	}
	
	@RequestMapping(value={"/edit/{id}"}, method = RequestMethod.POST)
	public String editCase(HttpServletRequest request, CaseInfo caseInfo,String[] drugIds,String[] actionsCheckbox,
			String[] abusetypeCheckbox,String[] insuranceTypeCheckbox,HttpSession session, @PathVariable Integer id) throws Exception{
		String currUser = (String)request.getSession().getAttribute("userName");
		caseService.updateCase(caseInfo, drugIds, actionsCheckbox, abusetypeCheckbox, insuranceTypeCheckbox, currUser, id);
		return "redirect:/case/detail/" + caseInfo.getId();
	}
	
	@ResponseBody
	@RequestMapping(value={"/recall/{id}"}, method = RequestMethod.POST)
	public AjaxResult recall(HttpServletRequest request, @PathVariable Integer id)
	{
	    operateLogger.info("[case/recall-updateCaseStatus]--Start--[id:"+id+"-caseStatus:"+CaseStatus.INPROCESS.getValue()+"-userName"
	            +request.getSession().getAttribute("userName").toString()+"]");
	    
		caseInfoService.updateCaseStatus(id, CaseStatus.INPROCESS.getValue(), request.getSession().getAttribute("userName").toString());
		return AjaxResult.SUCCESS;
	}
	
	@ResponseBody
	@RequestMapping(value={"/delete/{id}"}, method = RequestMethod.POST)
	public AjaxResult delete(HttpServletRequest request, @PathVariable Integer id)
	{
		operateLogger.info("[case/delete-updateCaseStatus]--Start--[id:"+id+"-caseStatus:"+CaseStatus.INPROCESS.getValue()+"-userName"
				+request.getSession().getAttribute("userName").toString()+"]");
		
		caseInfoService.updateCaseStatus(id, CaseStatus.DELETED.getValue(), request.getSession().getAttribute("userName").toString());
		return AjaxResult.SUCCESS;
	}
	
	@ResponseBody
	@RequestMapping(value={"/complete/{id}"}, method = RequestMethod.POST)
	public AjaxResult complete(HttpServletRequest request, @PathVariable Integer id)
	{
	    operateLogger.info("[case/complete-updateCaseStatus]--Start--[id:"+id+"-caseStatus:"+CaseStatus.INPROCESS.getValue()+"-userName"
                +request.getSession().getAttribute("userName").toString()+"]");
        
		caseInfoService.updateCaseStatus(id, CaseStatus.COMPLETED.getValue(), request.getSession().getAttribute("userName").toString());
		return AjaxResult.SUCCESS;
	}
	
	@ResponseBody
	@RequestMapping(value={"/invalid/{id}"}, method = RequestMethod.POST)
	public AjaxResult invalid(HttpServletRequest request, @PathVariable Integer id)
	{
	    operateLogger.info("[case/invalid-updateCaseStatus]--Start--[id:"+id+"-caseStatus:"+CaseStatus.INPROCESS.getValue()+"-userName"
                +request.getSession().getAttribute("userName").toString()+"]");
        
		caseInfoService.updateCaseStatus(id, CaseStatus.INVALID.getValue(), request.getSession().getAttribute("userName").toString());
		return AjaxResult.SUCCESS;
	}
	
	
	@RequestMapping(value={"/assign"}, method = RequestMethod.GET)
	public String AssignCase(HttpServletRequest request){
		List<String> countries = chapterService.queryAllCountries();
    	List<SelectOption> countryDatas = new ArrayList<SelectOption>();
    	if(countries != null && countries.size() > 0)
    	{
    		for (int i = 0; i < countries.size(); i++) {
        		SelectOption op = new SelectOption();
        		op.setLabel(countries.get(i));
        		op.setValue(countries.get(i));
        		countryDatas.add(op);
    		}
    	}
    	request.setAttribute("countryDatas", countryDatas);
        return "case/assign";
	}

	@RequestMapping(value={"/getChapterStaff"}, method = RequestMethod.POST)
	@ResponseBody
	public List<User> getChapterStaff(HttpServletRequest request){
		String chapter = request.getParameter("chapter");
        return userService.getUserBychapterId(Long.valueOf(chapter));
	}
	
	@RequestMapping(value={"/saveCaseToUser"}, method = RequestMethod.POST)
    @ResponseBody
    public Map<String,String> save(HttpServletRequest req,HttpServletResponse resp) throws IOException{
		
		String  currUser = (String) req.getSession().getAttribute("userName");
    	Map<String,String> data = new HashMap<String,String>();
    	String userId=req.getParameter("userId");
    	String caseId=req.getParameter("caseId");
    	String notes=req.getParameter("notes");
    	if(StringUtils.isBlank(userId)){
    		data.put("success", "N");
    		data.put("msg", "One chapter staff must be choosed!");
    		return data;
    	}
    	//old information
    	CaseInfo oldInfo = caseInfoService.getCaseInfoById(Integer.valueOf(caseId));

    	if(oldInfo.getUserId()!=null){
    		try {
    			List<String> needComparedFields = new ArrayList<String>();
    			
    			CaseInfo newInfo = new CaseInfo();
    			newInfo.setUserId(userId);
    			
    			needComparedFields.add("userId");

    			List<ChangeResult> changeResults;
    			changeResults = DataUtil.compareObjectByFields(oldInfo, newInfo, needComparedFields);
    			ChangeHistoryDisplayData displayData = new ChangeHistoryDisplayData();
    			if(changeResults.size() > 0)
    			{
    				CaseAudit audit2 = new CaseAudit();
    				audit2.setAction("Update");
    				audit2.setUpdatedTime(new Date());
    				audit2.setUpdatedBy(currUser);
    				audit2.setCaseId(Integer.valueOf(caseId));
    				StringBuilder updateContent = new StringBuilder();
    				for(ChangeResult changeResult : changeResults)
    				{	
    					
    						updateContent.append("Case has assignd from UserId:" ) 
    						.append("\"").append(changeResult.getOldValue()).append("\"").append(" to ").append("UserId:\"").append(changeResult.getNewValue()).append("\"")
    						.append("<br>");

    					
    				}
    				audit2.setUpdatedAfter(updateContent.toString());
    				caseAuditService.insertCaseAudit(audit2);
    			}
    		} catch (SecurityException | IllegalArgumentException | IllegalAccessException e1) {
    			e1.printStackTrace();
    		}
    	}else{
			CaseAudit audit2 = new CaseAudit();
			audit2.setAction("Update");
			audit2.setUpdatedTime(new Date());
			audit2.setUpdatedBy(currUser);
			audit2.setCaseId(Integer.valueOf(caseId));
			StringBuilder updateContent = new StringBuilder();
			updateContent.append("Case has assignd to UserId:").append("\"").append(userId).append("\"").append("<br>");;
			audit2.setUpdatedAfter(updateContent.toString());
			caseAuditService.insertCaseAudit(audit2);
    	}
    	caseInfoService.updateCaseStatus(Integer.valueOf(caseId), CaseStatus.ASSIGNED.getValue(), req.getSession().getAttribute("userName").toString());
    	int flag = caseInfoService.updateUserToCase(Integer.valueOf(userId), Integer.valueOf(caseId), notes);
    	if(flag<1){
    		data.put("success", "N");
    		data.put("msg", "assign case failed!");
    		return data;
    	}else{
    		try {
    			User user1 = userService.getUserById(Integer.valueOf(userId));
				sendNotification(caseInfoService.getCaseInfoById(Integer.valueOf(caseId)),"2",user1.getEmail(),notes);
				System.out.println("send assign notification successfully");
			} catch (NumberFormatException e) {
				exceptionLog.error("convert caseId to integer error, Line 847 in Save method");
				e.printStackTrace();
			} catch (Exception e) {
				exceptionLog.error("send notification after assign case error ");
				exceptionLog.error(e.toString());
			}
    	}
    	data.put("success", "Y");
    	return data;
    	
	 }
	@RequestMapping(value={"/assignDetail/{id}"}, method = RequestMethod.POST)
    @ResponseBody
    public Map<String,String> save(HttpServletRequest req, @PathVariable Integer id,HttpServletResponse resp) throws IOException{
		Map<String,String> data = new HashMap<String,String>();
		//根据caseId查询user信息
		CaseInfo info = caseInfoService.getCaseInfoById(id);
		if(info!=null&&!StringUtils.isBlank(info.getUserId())){
			//查询user相关信息
			User user = userService.getUserById(Integer.valueOf(info.getUserId()));
			data.put("chCountry",user.getCountry());
			data.put("chStates", user.getState());
			data.put("chCity", user.getCity());
			data.put("chapterId", String.valueOf(user.getChapterId()));
			data.put("chapterStaff", user.getUserName());
			data.put("notes", info.getNotes());
			data.put("success", "Y");
		}
    	return data;
	 }
}
